{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "#chap09 Python面向对象设计31\n",
    "class Car:\n",
    "    def infor(self):\n",
    "        print(\"This is a car\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "car=Car()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "This is a car\n"
     ]
    }
   ],
   "source": [
    "car.infor()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "isinstance(car,Car)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "isinstance(car,str)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Car:\n",
    "    price=100000                  #定义类属性\n",
    "    def __init__(self, c):\n",
    "        self.color=c           #定义实例属性"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "car1=Car(\"Red\")\n",
    "car2=Car(\"Blue\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Red 100000\n"
     ]
    }
   ],
   "source": [
    "print(car1.color, Car.price)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "Car.price=110000                 #修改类属性\n",
    "Car.name='QQ'                    #增加类属性\n",
    "car1.color=\"Yellow\"              #修改实例属性"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Blue 110000 QQ\n",
      "Yellow 110000 QQ\n"
     ]
    }
   ],
   "source": [
    "print(car2.color, Car.price, Car.name)\n",
    "print(car1.color, Car.price, Car.name)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`haha`等价于`self`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "class A:\n",
    "    def __init__(haha,v):\n",
    "        haha.value = v\n",
    "    def show(haha):\n",
    "        print(haha.value)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n"
     ]
    }
   ],
   "source": [
    "a=A(3)\n",
    "a.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "class A:\n",
    "    def __init__(self, value1 = 0, value2 = 0):\n",
    "        self._value1 = value1\n",
    "        self.__value2 = value2 #私有属性\n",
    "    def setValue(self, value1, value2):\n",
    "        self._value1 = value1\n",
    "        self.__value2 = value2\n",
    "    def show(self):\n",
    "        print(self._value1)\n",
    "        print(self.value2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = A()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a._value1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a._A__value2 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "8"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "3+5"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## `_`最后一次显示的内容作为输入"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "10"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "_+2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "ename": "AttributeError",
     "evalue": "'A' object has no attribute '__value2'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-18-0ec46ea76417>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0ma\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__value2\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mAttributeError\u001b[0m: 'A' object has no attribute '__value2'"
     ]
    }
   ],
   "source": [
    "a.__value2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "30"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "_*3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6.0"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "_/5\n",
    "#1/0    #error"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6.0"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Fruit:\n",
    "        def __init__(self):\n",
    "            self.__color = 'Red'\n",
    "            self.price = 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "apple=Fruit()\n",
    "apple.price"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "apple.price = 2\n",
    "apple.price"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2 Red\n"
     ]
    }
   ],
   "source": [
    "print(apple.price, apple._Fruit__color)     #访问私有成员"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2 Blue\n"
     ]
    }
   ],
   "source": [
    "apple._Fruit__color=\"Blue\"     #访问私有成员\n",
    "print(apple.price, apple._Fruit__color)\n",
    "#print(apple.__color )         #不能直接访问私有属性"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 Red\n"
     ]
    }
   ],
   "source": [
    "peach=Fruit()\n",
    "print(peach.price, peach._Fruit__color)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Root:\n",
    "    __total = 0\n",
    "    def __init__(self,v):\n",
    "            self.__value = v\n",
    "            Root.__total += 1\n",
    "    def show(self):\n",
    "            print('self.__value:',self.__value)\n",
    "            print('Root.__total:',Root.__total)\n",
    "    @classmethod\n",
    "    def classShowTotal(cls):\n",
    "            print(cls.__total)\n",
    "    @staticmethod\n",
    "    def staticShowTotal():\n",
    "            print(Root.__total)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "1\n",
      "self.__value: 3\n",
      "Root.__total: 1\n"
     ]
    }
   ],
   "source": [
    "r = Root(3)\n",
    "r.classShowTotal()\n",
    "r.staticShowTotal()\n",
    "r.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "2\n"
     ]
    }
   ],
   "source": [
    "rr = Root(3)\n",
    "Root.classShowTotal()\n",
    "Root.staticShowTotal()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "self.__value: 3\n",
      "Root.__total: 2\n",
      "self.__value: 3\n",
      "Root.__total: 2\n"
     ]
    }
   ],
   "source": [
    "#Root.show()    #Error No Param\n",
    "Root.show(r)\n",
    "\n",
    "r.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "## Python内置的`@property`装饰器就是负责把一个方法变成属性调用的\n",
    "- 只读\n",
    "- 不可删除\n",
    "- 不可修改"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "##For python3.5\n",
    "class Test:\n",
    "    def __init__(self, value):\n",
    "        self.__value = value\n",
    "    \n",
    "    @property  #将函数改变类或者实例的一个属性，只能访问，不能修改数值\n",
    "    def value(self):\n",
    "        return self.__value"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t = Test(3)\n",
    "t.value"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 临时创建属性和删除属性"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#t.value = 5  #error can't set attribute\n",
    "t.v = 5\n",
    "t.v"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "ename": "AttributeError",
     "evalue": "can't set attribute",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-40-b41a270b12f2>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mt\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mvalue\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m5\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mAttributeError\u001b[0m: can't set attribute"
     ]
    }
   ],
   "source": [
    "t.value = 5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "del t.v\n",
    "#del t.value   #Error can't delete attribute"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t.value"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "##For python3.5\n",
    "class Test:\n",
    "    def __init__(self, value):\n",
    "        self.__value = value    \n",
    "    def __get(self):\n",
    "        return self.__value\n",
    "    def __set(self, v):\n",
    "        self.__value = v\n",
    "    value = property(__get, __set)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t = Test(3)\n",
    "t.value"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t.value = 5\n",
    "t.value\n",
    "\n",
    "#del t.value  #Error can't delete attribute"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    " ###  通过`property()`来设置"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [],
   "source": [
    "##For python3.5\n",
    "class Test:\n",
    "    def __init__(self, value):\n",
    "        self.__value = value\n",
    "    def __get(self):\n",
    "        return self.__value\n",
    "    def __set(self, v):\n",
    "        self.__value = v\n",
    "    def __del(self):\n",
    "        del self.__value\n",
    "    \n",
    "    #通过property方法来设置，可以设置，查找和删除\n",
    "    value = property(__get, __set, __del) #具备get set和set\n",
    "    def show(self): \n",
    "        print(self.__value)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n"
     ]
    }
   ],
   "source": [
    "t = Test(3)\n",
    "t.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 因为有`__set`,`__get`,`__del`方法，所以修改，访问和删除"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5\n"
     ]
    }
   ],
   "source": [
    "t.value = 5\n",
    "t.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [],
   "source": [
    "del t.value\n",
    "#t.show()    #Error no attribute '_Test__value"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n"
     ]
    }
   ],
   "source": [
    "t.value =1\n",
    "t.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 类的特殊方法\n",
    "### 例：重载运算符，自定义数组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [],
   "source": [
    "#MyArray.py\n",
    "#Better change to ipython and use myQueue.py\n",
    "#cd /home/lab466/pythons/py35LessonPlusSpiderML/chp06\n",
    "# /home/lab466/pythons/py35LessonPlusSpiderML/chp06>python\n",
    "import os\n",
    "os.chdir('../ds/')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [],
   "source": [
    "from MyArray import MyArray"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = MyArray(1,2,3,4,5,6)\n",
    "y = MyArray(6,5,4,3,2,1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[6, 7, 8, 9, 10, 11]"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x+5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[3, 6, 9, 12, 15, 18]"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x*3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "56"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x.dot(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [],
   "source": [
    "x.append(7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 4, 5, 6, 7]"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The size must be equal.\n"
     ]
    }
   ],
   "source": [
    "x.dot(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 4, 5, 6, 7]"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Index type error or out of range\n"
     ]
    }
   ],
   "source": [
    "x[9] = 8"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5]"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x / 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 1, 1, 2, 2, 3, 3]"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x//2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 0, 1, 2, 0, 1]"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x % 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'a' in x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "3 in x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x < y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = MyArray(1,2,3,4,5,6)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[7, 7, 7, 7, 7, 7]"
      ]
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x + y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [],
   "source": [
    "#继承例子见\n",
    "#teacher.py\n",
    "#但这是一个运行在python2.7下面的例子\n",
    "\n",
    "##\n",
    "class A():\n",
    "    def __init__(self):\n",
    "        self.__private()\n",
    "        self.public()        \n",
    "    def __private(self):\n",
    "        print('__private() method of A')        \n",
    "    def public(self):\n",
    "        print('public() method of A')\n",
    "\n",
    "class B(A):\n",
    "    def __private(self):\n",
    "        print('__private() method of B')        \n",
    "    def public(self):\n",
    "        print('public() method of B')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "__private() method of A\n",
      "public() method of B\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "['_A__private',\n",
       " '_B__private',\n",
       " '__class__',\n",
       " '__delattr__',\n",
       " '__dict__',\n",
       " '__dir__',\n",
       " '__doc__',\n",
       " '__eq__',\n",
       " '__format__',\n",
       " '__ge__',\n",
       " '__getattribute__',\n",
       " '__gt__',\n",
       " '__hash__',\n",
       " '__init__',\n",
       " '__init_subclass__',\n",
       " '__le__',\n",
       " '__lt__',\n",
       " '__module__',\n",
       " '__ne__',\n",
       " '__new__',\n",
       " '__reduce__',\n",
       " '__reduce_ex__',\n",
       " '__repr__',\n",
       " '__setattr__',\n",
       " '__sizeof__',\n",
       " '__str__',\n",
       " '__subclasshook__',\n",
       " '__weakref__',\n",
       " 'public']"
      ]
     },
     "execution_count": 74,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b=B()\n",
    "dir(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Person(object):#基类必须继承于object\n",
    "    def __init__(self, name = '', age = 20, sex = 'man'):\n",
    "        self.setName(name)\n",
    "        self.setAge(age)\n",
    "        self.setSex(sex)\n",
    "        \n",
    "    def setName(self, name):\n",
    "        if type(name) != str:\n",
    "            print('name must be string.')\n",
    "            return\n",
    "        self.__name = name\n",
    "        \n",
    "    def setAge(self, age):\n",
    "        if type(age) != int:\n",
    "            print('age must be integer.')\n",
    "            return\n",
    "        self.__age = age\n",
    "        \n",
    "    def setSex(self, sex):\n",
    "        if sex != 'man' and sex != 'woman':\n",
    "            print('sex must be \"man\" or \"woman\"')\n",
    "            return\n",
    "        self.__sex = sex\n",
    "        \n",
    "    def show(self):\n",
    "        print(self.__name)\n",
    "        print(self.__age)\n",
    "        print(self.__sex)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Teacher(Person):\n",
    "    def __init__(self, name='', age = 30, sex = 'man', department = 'Computer'):\n",
    "        super(Teacher, self).__init__(name, age, sex) #调用父类的init方法\n",
    "        #Person.__init__(self, name, age, sex)\n",
    "        self.setDepartment(department)\n",
    "        \n",
    "    def setDepartment(self, department):\n",
    "        if type(department) != str:\n",
    "            print('department must be a string.')\n",
    "            return\n",
    "        self.__department = department\n",
    "        \n",
    "    def show(self):\n",
    "        super(Teacher, self).show()\n",
    "        print(self.__department)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Zhang San\n",
      "19\n",
      "man\n",
      "Li Si\n",
      "32\n",
      "man\n",
      "Math\n"
     ]
    }
   ],
   "source": [
    "if __name__ == '__main__':\n",
    "    zhangsan = Person('Zhang San', 19, 'man')\n",
    "    zhangsan.show()\n",
    "    lisi = Teacher('Li Si',32, 'man', 'Math')\n",
    "    lisi.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 描述\n",
    "- super() 函数是用于调用父类(超类)的一个方法。\n",
    "\n",
    "- super 是用来解决多重继承问题的，直接用类名调用父类方法在使用单继承的时候没问题，但是如果使用多继承，会涉及到查找顺序（MRO）、重复调用（钻石继承）等种种问题。\n",
    "\n",
    "- MRO 就是类的方法解析顺序表, 其实也就是继承父类方法时的顺序表。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n"
     ]
    }
   ],
   "source": [
    "class demoA:\n",
    "     def add(self, x):\n",
    "         y = x + 1\n",
    "         print(y)\n",
    "            \n",
    "class demoB(demoA):\n",
    "    def add(self, x):\n",
    "        super().add(x)\n",
    "b = demoB()\n",
    "b.add(2)  # 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
